﻿//===============================================================================
// Magic OQL
//===============================================================================
// Copyright ?Magic Thought Corporation. All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// Richie (http://www.cnblogs.com/RicCC)
// March 7, 2008
//===============================================================================

using Antlr.Runtime;
using Antlr.Runtime.Tree;

namespace SQLAnalyticLibrary.Expressions
{
    /// <summary>
    /// Named parameters: @name, :name, ?name. Positioned parameters:?.
    /// <para>{new UserVariable($UserVariable)}, using this style in grammar don't require <see cref="UserVariable"/> inherit from <see cref="CombinedKeywords"/></para>
    /// </summary>
    public class UserVariable : Expression
    {
        private int _position = -1;
        public UserVariable(Expression node)
            : base(node)
        {
        }
        public UserVariable(IToken t)
            : base(t)
        {
        }

        public bool IsNamedVar
        {
            get
            {
                return !this.IsNil && this.Text.Length > 1 && (this.Text[0] == '@' || this.Text[0] == '?' || this.Text[0] == ':');
            }
        }
        public bool IsPositionedVar
        {
            get
            {
                return !this.IsNil && this.Text.Length == 1 && this.Text == "?";
            }
        }
        public int Position
        {
            get { return this._position; }
            set { this._position = value; }
        }
        public override void VisitCompile(ICompileVisitor visitor)
        {
            if (this.IsPositionedVar) visitor.VisitPositionedVariable(this);
        }

        public override void VisitSql(ISqlVisitor visitor)
        {
            if (this.IsPositionedVar) visitor.PositionedVariable(this._position); //try to identify positioned variable
            else if (this.IsNamedVar) visitor.NamedVariable(this.Text); //try to identify named variable
        }

        internal static int TreeType
        {
            get
            {
                return OQLParser.UserVariable;
            }
        }
        public static bool IsUserVariable(Expression exp)
        {
            if (exp == null || exp.IsNil) return false;
            return exp.Type == OQLParser.UserVariable;
        }

    }
}
